package translate

import (
	"bytes"
	"crypto/sha256"
	_ "embed"
	"encoding/hex"
	"encoding/json"
	"fmt"
	"github.com/google/uuid"
	"io"
	"log"
	"net/http"
	"net/url"
	"time"
	"translate/config"
)

const requestUrl = "https://openapi.youdao.com/api"

var Language map[string]string

// 嵌入语言文本
//
//go:embed language.json
var languageTextFile string

func init() {
	err := json.Unmarshal([]byte(languageTextFile), &Language)
	if err != nil {
		log.Panicln("解析文件失败：", err.Error())
	}
}

type YoudaoTranslationResponse struct {
	TSpeakURL     string       `json:"tSpeakUrl"`
	RequestID     string       `json:"requestId"`
	Query         string       `json:"query"`
	Translation   []string     `json:"translation"`
	MTerminalDict TerminalDict `json:"mTerminalDict"`
	ErrorCode     string       `json:"errorCode"`
	Dict          DictInfo     `json:"dict"`
	Webdict       WebDict      `json:"webdict"`
	LangType      string       `json:"l"`
	IsWord        bool         `json:"isWord"`
	SpeakURL      string       `json:"speakUrl"`
}

// 嵌套结构体定义
type TerminalDict struct {
	URL string `json:"url"`
}

type DictInfo struct {
	URL string `json:"url"`
}

type WebDict struct {
	URL string `json:"url"`
}

func YouDaoTranslate(language, text string) (*YoudaoTranslationResponse, error) {

	youDaoDict := config.Conf.YouDaoDict

	params := url.Values{}
	params.Set("q", text)
	params.Set("from", "auto")
	params.Set("to", Language[language])
	params.Set("appKey", youDaoDict.AppID)
	salt, err := uuid.NewUUID()
	if err != nil {
		log.Panicln("生成uuid失败：", err.Error())
	}
	params.Set("salt", salt.String())

	//设置签名
	input := []rune(text)
	if len(input) > 20 {
		input = append(input[:10], []rune(fmt.Sprint(len(input)))...)
		var suffix = []rune(text)[len([]rune(text))-10:]
		input = append(input, suffix...)
	}

	now := time.Now().Unix()
	s := youDaoDict.AppID + string(input) + salt.String() + fmt.Sprint(now) + youDaoDict.SecretKey
	h := sha256.New()
	h.Write([]byte(s))
	sign := hex.EncodeToString(h.Sum(nil))
	params.Set("sign", sign)
	params.Set("signType", "v3")
	params.Set("curtime", fmt.Sprint(now))

	//发送请求
	resp, err := http.Post(requestUrl, "application/x-www-form-urlencoded;charset=utf-8", bytes.NewReader([]byte(params.Encode())))
	if err != nil {
		return nil, err
	}

	body := resp.Body
	defer body.Close()

	all, err := io.ReadAll(body)
	if err != nil {
		return nil, err
	}
	log.Println("响应内容：", string(all))
	var data YoudaoTranslationResponse
	if err = json.Unmarshal(all, &data); err != nil {
		return nil, err
	}

	return &data, nil
}
